<?php

namespace think\wework\Api;

use Exception;
use think\response\Redirect;
use think\wework\Abstracts\WeworkApiWithToken;

class OAuth extends WeworkApiWithToken
{
    const SNS_TYPE_BASEINFO = 'snsapi_base';
    const SNS_TYPE_PRIVATEINFO = 'snsapi_privateinfo';

    private static ?OAuth $instance = null;
    public static function getInstance(): OAuth
    {
        if(!self::$instance instanceof OAuth) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 获取授权的用户信息
     * @param string $type //获取类型：SNS_TYPE_BASEINFO, SNS_TYPE_PRIVATEINFO
     * @param string $redirect //回调地址
     * @param bool $needDetail //是否需要详细的信息
     * @return Redirect|array
     * @throws Exception
     */
    public function userInfo(string $type, string $redirect, bool $needDetail = false): Redirect|array
    {
        $state = input('state');
        $code = input('code');

        if (empty($code) || empty($state) || $state != 'authed') {

            $callback = urlencode($redirect);
            if($type == self::SNS_TYPE_BASEINFO) {
                $authorizeUri = sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=authed#wechat_redirect", $this->corpId, $callback);
            } else {
                $authorizeUri = sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_privateinfo&state=authed&agentid=%s#wechat_redirect", $this->corpId, $callback,$this->agentId);
            }
            return redirect($authorizeUri);
        }
        $needDetail = $needDetail && $type == self::SNS_TYPE_PRIVATEINFO ? $needDetail : false;
        return $this->getUserInfo($code, $needDetail);
    }


    /**
     * 获取用户信息
     * @param string $code
     * @param bool $needDetail
     * @return array
     * @throws Exception
     */
    private function getUserInfo(string $code, bool $needDetail = false): array
    {
        $query = [
            'code' => $code
        ];
        $result = $this->httpClient->get('user/getuserinfo', compact('query'))->toArray();

        if ($result['errcode'] != 0) throw new Exception("{$result['errmsg']}[{$result['errcode']}]", 5010);

        $result['is_staffer'] = !empty($result['user_ticket']);
        $userDetail = (!empty($result['user_ticket']) && $needDetail) ? $this->_getUserDetail($result['user_ticket']) : [];
//        $result['user_detail'] = $userDetail;
        return array_merge($result, $userDetail);
    }

    /**
     * 当用户是员工时，可获取员工的敏感信息如手机号个人码等
     * @param string $userTicket
     * @return array
     * @throws Exception
     */
    private function _getUserDetail(string $userTicket): array
    {
        $json = [
            'user_ticket' => $userTicket
        ];
        $result = $this->httpClient->post('user/getuserdetail', compact('json'))->toArray();

        if ($result['errcode'] != 0) throw new Exception("{$result['errmsg']}[{$result['errcode']}]", 5010);

        return $result;
    }

}
